package ads.pin.pinmon.dal;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import ads.pin.pinmon.entity.Creature;

/**
 * Classe de acesso a dados para a Criatura.
 * 
 * Save Query: insert into creature(name, kind, skill_a_id, skill_b_id, author)
 * values (?, ?, ?, ?, ?)
 * 
 * Deve ser utilizada apenas para a comunicacao com o database, contendo metodos
 * relacionados ao mesmo: Save(insert), Update, Select, Delete.
 * 
 * @author
 * 
 */
public class CreatureDAO {

	private EntityManager em = new EntityManager() {

		@Override
		public Object treatResultSet(ResultSet resultSet) throws SQLException {
			Creature creature = new Creature();
			SkillDAO skillA = new SkillDAO();
			SkillDAO skillB = new SkillDAO();

			creature.setId(resultSet.getInt("id"));
			creature.setName(resultSet.getString("name"));
			creature.setKind(resultSet.getString("kind"));
			creature.setSkillA(skillA.searchById(resultSet.getInt("skill_a_id")));
			creature.setSkillB(skillB.searchById(resultSet.getInt("skill_b_id")));
			creature.setAuthor(resultSet.getString("author"));
			return creature;
		}
	};

	/**
	 * Insere uma criatura no banco de dados.
	 * 
	 * @param creature
	 *            Criatura a ser inserida.
	 * @throws SQLException
	 */
	public void save(Creature creature) throws SQLException {
		String sql = "insert into creature(name, kind, skill_a_id, "
				+ "skill_b_id, author) values (?, ?, ?, ?, ?)";

		em.executeQuery(sql, creature.getName(), creature.getKind(), creature
				.getSkillA().getId(), creature.getSkillB().getId(), creature
				.getAuthor());

	}

	/**
	 * Atualiza a criatura no banco de dados.
	 * 
	 * @param creature
	 *            Criatura a ser atualizada.
	 * @throws SQLException
	 */
	public void update(Creature creature) throws SQLException {
		String sql = "update creature set name = ?, "
				+ "kind = ?, skill_a_id = ?, skill_b_id = ?, "
				+ "author = ? where id = ?";

		em.executeQuery(sql, creature.getName(), creature.getKind(), creature
				.getSkillA().getId(), creature.getSkillB().getId(), creature
				.getAuthor(), creature.getId());

	}

	/**
	 * Deleta uma criatura especifica.
	 * 
	 * @param id
	 *            Id da criatura a ser deletada.
	 * @throws SQLException
	 */
	public void deleteById(Integer id) throws SQLException {
		String sql = "delete from creature where id = ?";
		em.executeQuery(sql, id);

	}

	/**
	 * Deleta todas as criaturas da tabela.
	 * 
	 * @throws SQLException
	 */
	public void deleteAll() throws SQLException {
		String sql = "delete from creature";
		em.executeQuery(sql);

	}

	/**
	 * Retorna uma criatura especifica.
	 * 
	 * @param id
	 *            Id da criatura selecionada.
	 * @return Criatura escolhida.
	 * @throws SQLException
	 */
	public Creature searchById(Integer id) throws SQLException {
		String sql = "select id, name, kind, skill_a_id, skill_b_id, "
				+ "author where id = ?";
		return (Creature) em.getSingleResult(sql, id);

	}

	/**
	 * Retorna todas as criaturas e as coloca em uma lista.
	 * 
	 * @return Lista com as criaturas.
	 * @throws SQLException
	 */
	@SuppressWarnings("unchecked")
	public List<Creature> searchAll() throws SQLException {
		String sql = "select id, name, kind, skill_a_id, skill_b_id, "
				+ "author from creature";
		return (List<Creature>) em.getResultList(sql);
	}

}
